/*******************************************************************************
 * Level Master 2000
 * Copyright (C) 2010 Christian Herzog
 * For more information see http://code.google.com/p/levelmaster2000/
 *
 * This file is licensed under the terms of the MIT license, see
 * http://www.opensource.org/licenses/mit-license.php for further information.
 ******************************************************************************/
package com.zog
{
    import com.pblabs.animation.AnimatorComponent;
    import com.pblabs.box2D.Box2DSpatialComponent;
    import com.pblabs.components.basic.HealthComponent;
    import com.pblabs.components.basic.HealthEvent;
    import com.pblabs.engine.components.TickedComponent;
    import com.pblabs.engine.core.ObjectType;
    import com.pblabs.engine.debug.Logger;
    import com.pblabs.engine.entity.PropertyReference;
    import com.pblabs.engine.PBE;
    import com.zog.CharacterController;
    import flash.events.Event;
    import flash.geom.Point;

	public class PlayerLogic extends TickedComponent
	{
        //TODO: use PBE.callLater!
        
		public var positionProperty:PropertyReference = null;

        //Wheather player should be killed in next tick or not.
        private var killPlayer:Boolean = false;
        private var resetPlayer:Boolean = false;
        //private var oldCollidesWithTypes:ObjectType = new ObjectType();
        private var oldCollidesWithTypes:XML = new XML();

		protected override function onAdd():void
		{
			super.onAdd();
			owner.eventDispatcher.addEventListener(HealthEvent.DIED, onDied);
            owner.eventDispatcher.addEventListener(CreateEntityEvent.CREATE_ROLLING_STONE_EVENT, onCreateEntity);
            owner.eventDispatcher.addEventListener(ResetPlayerEvent.RESET_PLAYER, onResetPlayer);
		}
		
		protected override function onRemove():void
		{
			super.onRemove();
			owner.eventDispatcher.removeEventListener(HealthEvent.DIED, onDied);
            owner.eventDispatcher.removeEventListener(CreateEntityEvent.CREATE_ROLLING_STONE_EVENT, onCreateEntity);
            owner.eventDispatcher.removeEventListener(ResetPlayerEvent.RESET_PLAYER, onResetPlayer);
		}
		
        public override function onTick(tickRate:Number):void
        {
            if(killPlayer)
            {
                killPlayer = false;
                onKillPlayer();
            }
            else if(resetPlayer)
            {
                Logger.print(this, "resetPlayer");
                resetPlayer = false;
                var spatial:Box2DSpatialComponent = owner.lookupComponentByType(Box2DSpatialComponent) as Box2DSpatialComponent;
                if(spatial != null)
                {
                    //spatial.position = new Point( -192, 100);
                    //spatial.position = lastResetPlayerEvent.position;
                    spatial.position = resetPlayerPosition.clone();
                    //spatial.collidesWithTypes.deserialize(oldCollidesWithTypes);
                    //Logger.print(this, oldCollidesWithTypes.toXMLString());
                    spatial.collidesWithTypes = new ObjectType("Platform", "HurtObject", "Zone");
                    spatial.linearVelocity = new Point();
                }

                //Jump up a bit, and then fall to bottom of screen:
                var animator:AnimatorComponent = owner.lookupComponentByType(AnimatorComponent) as AnimatorComponent;
                animator.play("idle");

                
                var controller:CharacterController = owner.lookupComponentByType(CharacterController) as CharacterController;
                if(controller != null)
                {
                    controller.isActive = true;
                }                
            }
        }

      
        protected function onKillPlayer():void
        {
            var controller:CharacterController = owner.lookupComponentByType(CharacterController) as CharacterController;
            controller.isActive = false;
            
            //Jump up a bit, and then fall to bottom of screen:
            var spatial:Box2DSpatialComponent = owner.lookupComponentByType(Box2DSpatialComponent) as Box2DSpatialComponent;
            
            oldCollidesWithTypes = new XML();
            spatial.collidesWithTypes.serialize(oldCollidesWithTypes);
            //Logger.print(this, oldCollidesWithTypes.toXMLString());
            spatial.collidesWithTypes = new ObjectType("Zone");
            spatial.linearVelocity = new Point(0, -200);

            //Jump up a bit, and then fall to bottom of screen:
            var animator:AnimatorComponent = owner.lookupComponentByType(AnimatorComponent) as AnimatorComponent;
            animator.play("die");
            
            //Reset health:
            var health:HealthComponent = owner.lookupComponentByType(HealthComponent) as HealthComponent;
            if(health != null)
            {
                health.health = 100;
            }
            else
            {
                Logger.error(this, "onKillPlayer", "Entity " + owner.name + " has no HealthComponent.");
            }            
        }
        
		protected function onDied(event:Event):void
		{
           killPlayer = true;
		}
        
        //TODO: this ought to be in a common logic entity...
        protected function onCreateEntity(event:CreateEntityEvent):void
        {
            if (event.type == CreateEntityEvent.CREATE_ROLLING_STONE_EVENT)
            {
                PBE.callLater(PBE.makeEntity, [event.type, { "@Spatial.position": event.position }]);
            }
        }
        
        protected function onResetPlayer(event:ResetPlayerEvent):void
        {
            resetPlayer = true;
            lastResetPlayerEvent = event;
            resetPlayerPosition = event.position;
            //var spatial:Box2DSpatialComponent = owner.lookupComponentByType(Box2DSpatialComponent) as Box2DSpatialComponent;
            //spatial.position = event.position;
        }
		
        private var resetPlayerPosition:Point = null;
        private var lastResetPlayerEvent:ResetPlayerEvent = null;
	}
}